<?php
/**
 * licenses : MIT
 * creatTime: 2020/5/13
 * author : weblinuxgame
 * filename: ApiResponse.php
 */

namespace App\Core\Traits\Api;

use ArrayAccess;
use Illuminate\Http\Response;
use Illuminate\Http\ResponseTrait;
use Illuminate\Contracts\Support\Arrayable;
use Symfony\Component\HttpFoundation\Response as FoundationResponse;

/**
 * Trait ApiResponse
 * @package App\Core\Traits\Api
 */
trait ApiResponse
{
    use ResponseTrait, TransformTrait;

    /**
     * @var int
     */
    protected $statusCode = FoundationResponse::HTTP_OK;

    /**
     * @return int
     */
    public function getStatusCode()
    {
        return $this->statusCode;
    }

    /**
     * @param $statusCode
     * @return static
     */
    public function setStatusCode($statusCode)
    {
        $this->statusCode = $statusCode;
        return $this;
    }

    /**
     * @param $data
     * @param array $header
     * @return Response
     */
    public function respond($data, $header = [])
    {
        if (is_array($data)) {
            if (!isset($data['data'])) {
                $data['data'] = null;
            }
        } else {
            $data = ['data' => $data];
        }
        if (!isset($data['code'])) {
            $data['code'] = $this->getStatusCode();
        }
        return response(self::transform($data), FoundationResponse::HTTP_OK, $header);
    }

    /**
     * @param $status
     * @param array $data
     * @param null $code
     * @return Response
     */
    public function status($status, array $data, $code = null)
    {

        if ($code) {
            $this->setStatusCode($code);
        }

        $status = [
            'status' => $status,
            'httpCode' => $this->statusCode
        ];
        if (!isset($data['data'])) {
            $data = compact('data');
        }
        $data = array_merge($status, $data);
        return $this->respond($data);

    }

    /**
     * @param $message
     * @param int $code
     * @param string $status
     * @return Response
     */
    public function failed($message, $code = FoundationResponse::HTTP_BAD_REQUEST, $status = 'error')
    {
        return $this->setStatusCode($code)->message($message, $status);
    }

    /**
     * @param $message
     * @param string $status
     * @return Response
     */
    public function message($message, $status = "success")
    {

        return $this->status($status, [
            'message' => $message
        ]);
    }

    /**
     * @param string $message
     * @return Response
     */
    public function internalError($message = "Internal Error!")
    {
        return $this->failed($message, FoundationResponse::HTTP_INTERNAL_SERVER_ERROR);
    }

    /**
     * @param string $message
     * @return Response
     */
    public function created($message = "created")
    {
        return $this->setStatusCode(FoundationResponse::HTTP_CREATED)
            ->message($message);

    }

    /**
     * @param $data
     * @param string $status
     * @return Response
     */
    public function success($data, $status = "success")
    {
        if (!is_array($data)) {
            if ($data instanceof Arrayable) {
                $data = $data->toArray();
            } else if ($data instanceof ArrayAccess) {
                $data = array_copy($data);
            } else {
                $data = compact('data');
            }
        }
        return $this->status($status, $data);
    }

    /**
     * @param string $message
     * @return Response
     */
    public function notFond($message = 'Not Fond!')
    {
        return $this->failed($message, Foundationresponse::HTTP_NOT_FOUND);
    }

    /**
     * @param string $message
     * @return Response
     */
    public function unAuthorized($message = 'Please Login!')
    {
        return $this->failed($message, FoundationResponse::HTTP_UNAUTHORIZED);
    }

}

